# import jusmargui
from PySide2.QtWidgets import (
    QApplication,
    QWidget,
    QTableWidgetItem,
    QTableWidget,
    QHeaderView,
    QAbstractItemView,
    QVBoxLayout,
    QTabWidget,
    QGroupBox,
    QLabel,
    QLineEdit,
    QHBoxLayout,
    QGridLayout,
    QComboBox,
    QPushButton,
)
from PySide2.QtCore import Qt, Signal
from PySide2.QtGui import QPixmap, QDoubleValidator, QIntValidator, QImage
import sys
import csv
import os
import json
import subprocess
import re
from gui.controls import envs
from .. import config as Config
from ..utils import Utils
from ..dlg_model_params import DlgModeResetCls
from ..params_table import ParamsTable, OnlyOneRowTable
from ..util.parameter_mapping import (
    StageConnectionMap,
    StageConnectionReverseMap,
    typeSectionMap,
    typeSectionReverseMap,
)
from .. import message_box as MBox
from ..util.utils_empty import var_is_empty
from ..custom_widget import SelectBox, LineEditInt, MultRadioBtnGroup, SelectSearchBox


class DlgStageConnection(DlgModeResetCls):
    stageConnection_save_signal = Signal(object)

    def __init__(self, parent=None, params={}):
        super().__init__(parent)
        self.setWindowTitle("子模型连接")
        self.resize(400, 450)

        self.connects = params.get("connects") or {}
        self.info = self.parseContects(self.connects)

        layoutWrap = QHBoxLayout()
        layout = QVBoxLayout()
        layoutWrap.addStretch(1)
        layoutWrap.addLayout(layout)
        layoutWrap.addStretch(1)
        self.widgetDict = {}

        gridLayout = QGridLayout()
        self.section1GroupBox = QGroupBox(
            self.connects.get("connectsTitles")[0].get("title")
        )
        section1Layout = QVBoxLayout()
        section1LayoutWrap = QHBoxLayout()
        section1LayoutWrap.addStretch(1)
        section1LayoutWrap.addLayout(section1Layout)
        section1LayoutWrap.addStretch(1)
        self.section1GroupBox.setLayout(section1LayoutWrap)
        self.widgetDict["section1"] = SelectBox(
            options=[
                {"title": "点", "value": "点"},
                {"title": "面", "value": "面"},
                {"title": "自由", "value": "自由"},
            ],
            onChanged=lambda *args, **kwargs: self.section1Changed(
                self, *args, **kwargs
            ),
        )

        self.widgetDict["section1Value"] = SelectSearchBox(options=[])
        self.widgetDict["section1"].setFixedWidth(150)
        self.widgetDict["section1Value"].setFixedWidth(150)
        section1Layout.addWidget(self.widgetDict["section1"])
        section1Layout.addWidget(self.widgetDict["section1Value"])

        self.section2GroupBox = QGroupBox(
            self.connects.get("connectsTitles")[1].get("title")
        )
        section2LayoutWrap = QHBoxLayout()
        section2Layout = QVBoxLayout()
        section2LayoutWrap.addStretch(1)
        section2LayoutWrap.addLayout(section2Layout)
        section2LayoutWrap.addStretch(1)
        self.section2GroupBox.setLayout(section2LayoutWrap)
        self.widgetDict["section2"] = SelectBox(
            options=[
                {"title": "点", "value": "点"},
                {"title": "面", "value": "面"},
                {"title": "自由", "value": "自由"},
            ],
            onChanged=lambda *args, **kwargs: self.section2Changed(
                self, *args, **kwargs
            ),
        )
        self.widgetDict["section2Value"] = SelectSearchBox(options=[])
        self.widgetDict["section2"].setFixedWidth(150)
        self.widgetDict["section2Value"].setFixedWidth(150)
        section2Layout.addWidget(self.widgetDict["section2"])
        section2Layout.addWidget(self.widgetDict["section2Value"])

        icon = envs.qicons.qicon_add()
        addImg = QLabel()
        addImg.setAlignment(Qt.AlignCenter)
        pixmap = icon.pixmap(20, 20)
        addImg.setPixmap(pixmap)

        gridLayout.addWidget(self.section1GroupBox, 0, 0)
        gridLayout.addWidget(addImg, 0, 1)
        gridLayout.addWidget(self.section2GroupBox, 0, 2)

        self.connectionIdWidget = self.createContentNumWidget()
        connectionIdLayout = QHBoxLayout()
        layout.addLayout(connectionIdLayout)
        connectionIdLayout.addWidget(self.connectionIdWidget)
        connectionIdLayout.addStretch(1)

        layout.addLayout(gridLayout)

        self.tempLayout = QHBoxLayout()
        self.surfaceWidget = self.createSurfaceWidget()
        self.con_height = self.createCon_heightWidget()
        self.freeWidget = self.createFreeWidget()
        self.surfaceWidget.setVisible(False)
        self.con_height.setVisible(False)
        self.freeWidget.setVisible(False)

        self.tempLayout.addWidget(self.surfaceWidget)
        self.tempLayout.addWidget(self.con_height)
        layout.addLayout(self.tempLayout)
        layout.addWidget(self.freeWidget)

        layout.addStretch(1)

        btnLayout = QHBoxLayout()
        cancelBtn = QPushButton("取消")
        okBtn = QPushButton("确定")

        btnLayout.setAlignment(Qt.AlignCenter)
        btnLayout.addWidget(okBtn)
        btnLayout.addWidget(cancelBtn)
        layout.addLayout(btnLayout)

        okBtn.clicked.connect(self.on_okBtn_clicked)
        cancelBtn.clicked.connect(self.close)

        self.setLayout(layoutWrap)

        self.setStageOptions(
            options=(self.info.get("options0") or {}),
            select=self.widgetDict["section1"],
        )
        section1Value = self.widgetDict["section1"].getValue() or ""
        self.setStageOptions(
            options=(self.info.get("options1") or {}),
            select=self.widgetDict["section2"],
            previous=section1Value,
        )

        self.updateUI(params.get("data") or {})

    def parseContects(self, contects):
        optionsDict1 = {}
        optionsDict2 = {}

        sections = contects.get("stages") or []
        stage0 = sections[0].get("sections") or {}
        for i, item in enumerate(stage0):
            data = item.get("data") or {}

            if data.get("type") == "shell_bar" or data.get("type") == "bar_3d":
                ids = self.getIds(type=data.get("type"), data=data)
                optionsDict1["f"] = (optionsDict1.get("f") or []) + ids
            elif data.get("type") == "point_mass" or data.get("type") == "bar_conm":
                ids = self.getIds(type=data.get("type"), data=data)
                optionsDict1["p"] = (optionsDict1.get("p") or []) + ids
            elif data.get("type") == "bdf":
                optionsDict1["bdf"] = []

        stage1 = sections[1]
        stage1 = sections[1].get("sections") or {}
        for i, item in enumerate(stage1):
            data = item.get("data") or {}

            if data.get("type") == "shell_bar" or data.get("type") == "bar_3d":
                ids = self.getIds(type=data.get("type"), data=data)
                optionsDict2["f"] = (optionsDict2.get("f") or []) + ids
            elif data.get("type") == "point_mass" or data.get("type") == "bar_conm":
                ids = self.getIds(type=data.get("type"), data=data)
                optionsDict2["p"] = (optionsDict2.get("p") or []) + ids
            elif data.get("type") == "bdf":
                optionsDict2["bdf"] = []

        converted_dict1 = Utils.convertedSortAndFormat(optionsDict1)
        converted_dict2 = Utils.convertedSortAndFormat(optionsDict2)

        dataDict = {}

        dataDict["options0"] = converted_dict1
        dataDict["options1"] = converted_dict2

        return dataDict

    def getIds(self, type, data={}):
        ids = []
        if data:
            if type == "shell_bar":
                ringFrameData = (data.get("grid_set") or [[]]) + (
                    data.get("grid_ring") or [[]]
                )
                for item in ringFrameData:
                    if len(item) > 0:
                        ids.append(item[0])
            elif type == "bar_3d":
                if data.get("grid"):
                    if len(data.get("grid")) > 0 and len(data["grid"][0]) > 0:
                        ids.append(data["grid"][0][0])
                    if len(data.get("grid")) > 1 and len(data["grid"][1]) > 0:
                        ids.append(data["grid"][1][0])
            elif type == "point_mass":
                ids.append(data.get("grid_id"))
            elif type == "bar_conm":
                grid = data.get("grid") or []
                for item in grid:
                    if item and isinstance(item, list) and len(item) > 0:
                        ids.append(item[0])

        ids = [item for item in ids if item is not None]

        return ids

    def createContentNumWidget(self):
        connectionIdWidget = QWidget()
        connectionIdWidget.setFixedWidth(240)
        connectionIdLayout = QGridLayout()
        label1 = QLabel("连接的自由度")
        self.widgetDict["connectionId"] = LineEditInt()
        self.widgetDict["connectionId"].setClearButtonEnabled(False)
        self.widgetDict["connectionId"].setValue(123456)
        connectionIdLayout.addWidget(label1, 0, 0)
        connectionIdLayout.addWidget(self.widgetDict["connectionId"], 0, 1)

        label2 = QLabel("id")
        self.widgetDict["id"] = LineEditInt()
        self.widgetDict["id"].setClearButtonEnabled(False)
        connectionIdLayout.addWidget(label2, 1, 0)
        connectionIdLayout.addWidget(self.widgetDict["id"], 1, 1)

        connectionIdWidget.setLayout(connectionIdLayout)
        return connectionIdWidget

    def getStageOptionData(self, select, index):
        options = []

        ls = self.info.get(f"options{index}")
        if select == "点":
            options = ls.get("p") or []
        elif select == "面":
            options = ls.get("f") or []

        return options

    def createSurfaceWidget(self):
        surfaceGroupBox = QGroupBox("Group")
        surfaceLayout = QVBoxLayout()

        self.widgetDict["allAround"] = MultRadioBtnGroup(
            options=[{"title": "周向全选", "value": "周向全选"}],
            onChanged=lambda *args, **kwargs: self.selectAllChanged(*args, **kwargs),
        )
        surfaceLayout.addWidget(self.widgetDict["allAround"])
        self.widgetDict["surfaceTable"] = ParamsTable(rows=0, columns=2)
        self.widgetDict["surfaceTable"].setHorizontalHeaderLabels(
            [
                "约束角度",
                "约束范围",
            ]
        )
        self.widgetDict["surfaceTable"].rowSetFloat([0, 1])
        surfaceLayout.addWidget(self.widgetDict["surfaceTable"])
        surfaceGroupBox.setLayout(surfaceLayout)
        return surfaceGroupBox

    def createCon_heightWidget(self):
        con_heightGroupBox = QGroupBox("con_height")
        con_heightLayout = QVBoxLayout()

        self.widgetDict["con_height"] = OnlyOneRowTable(
            rows=0, columns=2, isNoAddAndDel=True
        )
        self.widgetDict["con_height"].setHorizontalHeaderLabels(
            ["起始高度", "终止高度"]
        )
        self.widgetDict["con_height"].rowSetFloat([0, 1])
        self.widgetDict["con_height"].addRow()
        con_heightLayout.addWidget(self.widgetDict["con_height"])
        con_heightGroupBox.setLayout(con_heightLayout)
        return con_heightGroupBox

    def createFreeWidget(self):
        self.widgetDict["freeTable"] = OnlyOneRowTable(
            rows=0, columns=2, isNoAddAndDel=True
        )
        self.widgetDict["freeTable"].setHorizontalHeaderLabels(
            [
                "主节点",
                "从节点",
            ]
        )
        self.widgetDict["freeTable"].rowSetInt([0, 1])
        self.widgetDict["freeTable"].addRow()
        return self.widgetDict["freeTable"]

    def selectAllChanged(self, *args, **kwargs):
        value = self.widgetDict["allAround"].getValue()
        if value and len(value) >= 1:
            self.widgetDict["surfaceTable"].setEnabled(False)
        else:
            self.widgetDict["surfaceTable"].setEnabled(True)

    def section1Changed(self, *args):

        if args[1] == "点":

            self.setStageOptions(
                options=self.info.get("options1") or {},
                select=self.widgetDict["section2"],
                previous="点",
                isFree=False,
            )
            options = self.getStageOptionData("点", 0)
            self.widgetDict["section1Value"].updateItem(options)
            self.widgetDict["section1Value"].setVisible(True)
            self.widgetDict["section2Value"].setVisible(True)

        if args[1] == "面":
            self.setStageOptions(
                options=self.info.get("options1") or {},
                select=self.widgetDict["section2"],
                previous="面",
                isFree=False,
            )
            options = self.getStageOptionData("面", 0)
            self.widgetDict["section1Value"].updateItem(options)
            self.widgetDict["section1Value"].setVisible(True)
            self.widgetDict["section2Value"].setVisible(True)
        elif args[1] == "自由":
            self.setStageOptions(
                options=self.info.get("options1") or {},
                select=self.widgetDict["section2"],
                previous="自由",
            )
            self.widgetDict["section1Value"].setVisible(False)
            self.widgetDict["section2Value"].setVisible(False)
        self.showTable()

    def section2Changed(self, *args):
        if args[1] == "点":
            options = self.getStageOptionData("点", 1)
            self.widgetDict["section2Value"].updateItem(options)
        if args[1] == "面":
            options = self.getStageOptionData("面", 1)
            self.widgetDict["section2Value"].updateItem(options)
        self.showTable()

    def showTable(self):
        if (
            self.widgetDict["section1"].getValue() == "面"
            or self.widgetDict["section2"].getValue() == "面"
        ):
            self.surfaceWidget.setVisible(True)
            self.freeWidget.setVisible(False)
        elif (
            self.widgetDict["section1"].getValue() == "自由"
            or self.widgetDict["section2"].getValue() == "自由"
        ):
            self.surfaceWidget.setVisible(False)
            self.freeWidget.setVisible(True)
        else:
            self.surfaceWidget.setVisible(False)
            self.freeWidget.setVisible(False)

        if (
            self.widgetDict["section1"].getValue() == "点"
            and self.widgetDict["section2"].getValue() == "面"
        ):

            self.con_height.setVisible(True)
        elif (
            self.widgetDict["section1"].getValue() == "面"
            and self.widgetDict["section2"].getValue() == "点"
        ):

            self.con_height.setVisible(True)
        else:
            self.con_height.setVisible(False)

    def setStageOptions(self, options, select, previous="", isFree=True):
        #   判断两个是什么连接
        opt = []

        if "p" in options:
            if previous == "点" or previous == "面" or previous == "":
                if {"title": "点", "value": "点"} not in opt:
                    opt.append({"title": "点", "value": "点"})
        if "f" in options:
            if previous == "点" or previous == "面" or previous == "":
                if {"title": "面", "value": "面"} not in opt:
                    opt.append({"title": "面", "value": "面"})
        if "bdf" in options:
            if previous == "自由" or previous == "":
                if {"title": "自由", "value": "自由"} not in opt:
                    opt.append({"title": "自由", "value": "自由"})
        select.updateItem(opt)

    def on_okBtn_clicked(self):
        dict = {}
        for key, widget in self.widgetDict.items():
            if key == "id":
                idValue = widget.getValue()
                if var_is_empty(idValue):
                    MBox.warning("id不可为空!")
                    return
            if widget.isVisible() and widget.isEnabled():
                if key == "allAround":
                    if len(widget.getValue()) >= 1:
                        dict[StageConnectionMap[key]] = True
                    else:
                        dict[StageConnectionMap[key]] = False

                elif isinstance(widget, QTableWidget):
                    temp = widget.getTableData()
                    if key == "freeTable" or key == "con_height":
                        if temp and len(temp) >= 1:
                            dict[StageConnectionMap[key]] = temp[0]
                    # elif key == "con_height":
                    #     dict[StageConnectionMap[key]] = [item[0] for item in temp if item and item[0] not in [None, ""]]
                    else:
                        dict[StageConnectionMap[key]] = temp
                else:
                    if key == "section1" or key == "section2":
                        continue
                    dict[StageConnectionMap[key]] = widget.getValue()

        dict["type"] = (
            str(typeSectionMap.get(self.widgetDict["section1"].getValue()))
            + "2"
            + str(typeSectionMap.get(self.widgetDict["section2"].getValue()))
        )
        dict["part1"] = self.connects.get("connectsTitles")[0].get("title")
        dict["part2"] = self.connects.get("connectsTitles")[1].get("title")

        dict = Utils.filter_dict_list(dict)
        dict = Utils.filterDictEmptyProperty(dict)
        self.cacheFile = Config.cachePath + "test111.json"
        Utils.write_json(self.cacheFile, dict)
        self.close()
        self.stageConnection_save_signal.emit(dict)

    def updateUI(self, data):
        if data:
            for key, value in data.items():
                widget = StageConnectionReverseMap.get(key)
                if widget in self.widgetDict:
                    if widget == "allAround":
                        if value:
                            self.widgetDict[widget].setValue(["周向全选"])
                            self.widgetDict["surfaceTable"].setEnabled(False)
                        else:
                            self.widgetDict["surfaceTable"].setEnabled(True)
                    elif isinstance(self.widgetDict[widget], QTableWidget):
                        if widget == "freeTable" or widget == "con_height":
                            if value:
                                temp = [value]
                        else:
                            temp = value
                        for rowData in temp:
                            if widget == "con_height" or widget == "freeTable":
                                self.widgetDict[widget].fillRowData(
                                    row=0, rowData=rowData
                                )
                            else:
                                self.widgetDict[widget].addRow(rowData=rowData)
                    elif isinstance(self.widgetDict[widget], QComboBox):
                        self.widgetDict[widget].setValue(str(value))
                    else:
                        if widget == "section1" or widget == "section2":
                            continue
                        self.widgetDict[widget].setValue(value)

                type = data.get("type")
                if type and "2" in type:
                    parts = re.split(r"2", type)  # 使用数字作为分隔符分割字符串
                    self.widgetDict["section1"].setValue(
                        typeSectionReverseMap.get(parts[0])
                    )
                    self.widgetDict["section2"].setValue(
                        typeSectionReverseMap.get(parts[-1])
                    )
            self.widgetDict["section1Value"].setValue(Utils.toInt(data.get("con_id1")))
            self.widgetDict["section2Value"].setValue(Utils.toInt(data.get("con_id2")))


# if __name__ == "__main__":
#     app = QApplication(sys.argv)
#     window = StageConnectionDialog()
#     window.show()
#     sys.exit(app.exec_())
